<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/4/13
 * Time: 10:16
 */

namespace frontend\ext;

use common\pay\wxpay\core\JsApiPay;
use common\pay\wxpay\core\WxPayApi;
use frontend\models\News;
use frontend\models\Order;
use frontend\models\ThirdCode;
use frontend\models\UserConsultation;
use yii\base\Exception;
use common\sms\SmsHelper;
use frontend\models\User;
use frontend\models\UserArticle;
use frontend\models\OrderDetailMember;
use frontend\models\UserMember;
use frontend\models\UserRight;
use frontend\models\Member;
use frontend\models\RelMemberRight;
use frontend\models\UserUsedVaService;
use common\pay\wxpay\core\WxPayUnifiedOrder;

class Pay
{

    /**
     * 获取微信api支付的参数
     * @param $order
     * @return \common\pay\wxpay\core\json数据
     * @throws \common\pay\wxpay\core\WxPayException
     */
    public static function GetWxJsApiParameters($order)
    {
        $tools = new JsApiPay();
        $openId = \Yii::$app->session['openid'];
        $input = new WxPayUnifiedOrder();
        $input->SetBody("三方惠诊");
        $input->SetOut_trade_no($order->trade_no);
        $input->SetTotal_fee(($order->price_payable) * 100);
        $input->SetNotify_url('http://' . $_SERVER['HTTP_HOST'] . \Yii::$app->urlManager->createUrl(['notify/wxnotify']));
        $input->SetTrade_type("JSAPI");
        $input->SetOpenid($openId);
        $wxorder = WxPayApi::unifiedOrder($input);
        $jsApiParameters = $tools->GetJsApiParameters($wxorder);

//获取共享收货地址js函数参数
//$editAddress = $tools->GetEditAddressParameters();
        return $jsApiParameters;
    }

    /*
     * 支付回调
     * $number 	//流水号
     * $paid_method //支付方式id 1 微信支付
     * $price //支付价格 单位元
     * ding
     * 2017-4-13
     */
    public static function PayCallBack($trade_no, $price, $paid_method)
    {
        $transaction = \Yii::$app->controller->module->db->beginTransaction();
        try {
            $order = Order::find()->where(['trade_no' => $trade_no])->one();
            if (empty($order)) {
                throw new Exception("订单不存在");
            }
            //验证状态
            if ($order->is_paid == '1') {//等待支付回调
                throw new Exception("订单已支付");
            }
            //验证价格
            if ($order->price_payable != $price) {
                throw new Exception("价格不对");
            }
            //更新订单信息
            $order->is_paid = 1;
            $order->paid_method = $paid_method;
            $order->paid_time = date('Y-m-d H:i:s');
            if (!$order->save()) {
                throw new Exception("订单更新失败");
            }
            switch ($order->order_type) {
                case "0"://购买文章阅读权限
                    static::OrderType0($order);
                    break;
                case "1"://购买咨询
                    static::OrderType1($order);
                    break;
                case "2"://购买会员
                    static::OrderType2345($order);
                    break;
                case "3"://购买会员升级包
                    static::OrderType2345($order);
                    break;
                case "4"://赠送会员
                    static::OrderType2345($order);
                    break;
                case "5"://会员续费
                    static::OrderType2345($order);
                    break;
                default:
                    throw new Exception("订单类型异常：" . $order->order_type);
            }

            $transaction->commit();
            return true;
        } catch (Exception $e) {
            $transaction->rollBack();
            \Yii::info($e->getMessage(), 'orders');
            return "异常：" . (empty($msg) ? $e->getMessage() : $msg);
        }
    }

    /**
     * 购买文章阅读权限
     * @param $order
     * @return string
     * @throws Exception
     */
    private static function OrderType0($order)
    {
        $userArticle = UserArticle::find()->where(['o_order_id' => $order->id])->one();
        if (empty($userArticle)) {
            throw new Exception("异常，该订单信息中未预存预购文章信息");
        }
        if (!empty($userArticle->is_active)) {
            throw new Exception("已拥有文章阅读权限，无需再支付");
        }
        $userArticle->is_active = 1;
        if (!$userArticle->save()) {
            throw new Exception("修改用户可阅读文章状态失败");
        }
    }

    /**
     * 购买咨询
     * @param $order
     * @return string
     * @throws Exception
     */
    private static function OrderType1($order)
    {
        $consultation = UserConsultation::find()->where(['o_order_id' => $order->id])->one();
        if (empty($consultation)) {
            throw new Exception("咨询不存在");
        }
        if ($consultation->is_paid == '1')
            throw new Exception("咨询已支付，不可重复支付");
        $consultation->is_paid = 1;
        if (!$consultation->save())
            throw new Exception("咨询更新异常");
    }

    /**
     * 2购买会员、3购买会员升级包、4赠送会员、5会员续费
     * @param $order
     * @return string
     * @throws Exception
     */
    private static function OrderType2345($order)
    {
        //特殊方法——删除非会员的user_right信息，更新会员信息
        $deadUserMembers = UserMember::find()->where(['or', ['is_active' => 0], ['<', 'expiration_time', date('Y-m-d H:i:s')]])->asArray()->all();
        $arr = empty($deadUserMembers) ? [] : array_column($deadUserMembers, 'o_user_id');
        UserRight::deleteAll(['in', 'o_user_id', $arr]);
        UserMember::updateAll(['is_active' => 0], ['<', 'expiration_time', date('Y-m-d H:i:s')]);

        $orderDetailMembers = OrderDetailMember::find()->where(['o_order_id' => $order->id, 'is_del' => 0])->all();
        if (empty($orderDetailMembers)) {
            throw new Exception("异常，未找到该订单的详细信息");
        }

        foreach ($orderDetailMembers as $orderDetailMember) {
            $get_user = User::findOne($orderDetailMember->o_get_user_id);
            if (empty($get_user)) {
                throw new Exception('异常，该用户不存在');
            }

            $member = Member::find()->where(['is_del' => 0, 'id' => $orderDetailMember->o_member_id])->one();
            if (empty($member)) {
                throw new Exception('异常，该' . ($member->level == 0 ? '会员' : '升级包') . '商品已不存在');
            }

            $userMember = UserMember::find()->where(['o_user_id' => $orderDetailMember->o_get_user_id, 'is_active' => 1])->andWhere(['>', 'expiration_time', date('Y-m-d H:i:s')])->one();
            if (!empty($userMember)) {//用户是会员
                $my_member_exists = Member::find()->where(['id' => $userMember->o_member_id, 'is_del' => 0])->one();
                if (empty($my_member_exists)) {
                    throw new Exception("异常数据，请联系管理员");
                } else {
                    $my_user_member_level = $my_member_exists->level;
                }
            } else {//用户不是会员，则我的会员等级为-1
                $my_user_member_level = -1;
            }

            if (in_array($order->order_type, [2, 3, 4])) {//2购买会员、3购买会员升级包、4赠送会员
                //如果我的会员等级 大于等于 预购会员或升级包的等级，则不允许购买
                //如果我不是会员，则不允许购买升级包
                if ($my_user_member_level >= $member->level || ($my_user_member_level == -1 && $member->level > 0)) {
                    throw new Exception("无权购买该商品");
                }

                //设置会员信息
                $userMemberExists = UserMember::find()->where(['o_user_id' => $orderDetailMember->o_get_user_id])->one();
                $userMemberNew = empty($userMemberExists) ? new UserMember : $userMemberExists;
                $userMemberNew->o_user_id = $orderDetailMember->o_get_user_id;
                $userMemberNew->o_member_id = $member->id;
                $userMemberNew->expiration_time = date('Y-m-d H:i:s', time() + 3600 * 24 * 365);//新购会员或升级，会员有效期设为今后的一年
                $userMemberNew->is_active = 1;
                if (!$userMemberNew->save()) {
                    throw new Exception("保存会员信息失败");
                }
                //设置权益（次数）使用信息
                $relMemberRights = RelMemberRight::find()
                    ->select('*')
                    ->leftJoin('right', 'right.id=rel_member_right.o_right_id')
                    ->where(['rel_member_right.o_member_id' => $member->id])
                    ->andWhere(['in', 'right.right_form', [1, 3, 4, 5]])
                    ->asArray()->all();
                $oldUserRights = UserRight::find()
                    ->select('right.right_type,sum(user_right.used_times) as used_times')
                    ->leftJoin('right', 'right.id=user_right.o_right_id')
                    ->where(['o_user_id' => $orderDetailMember->o_get_user_id])
                    ->groupBy('right.right_type')
                    ->asArray()->all();
                $oldRights = array_column($oldUserRights, 'used_times', 'right_type');
                UserRight::deleteAll(['o_user_id' => $orderDetailMember->o_get_user_id]);
                foreach ($relMemberRights as $relMemberRight) {
                    $total_times = empty($relMemberRight['free_times']) ? 1 : $relMemberRight['free_times'];
                    $used_times = empty($oldRights[$relMemberRight['right_type']]) ? 0 : $oldRights[$relMemberRight['right_type']];
                    if (in_array($relMemberRight['right_form'], [5])) {//如果是赠送保险，则直接使用
                        $used_times = $total_times;
                        $userUsedVaService = new UserUsedVaService;
                        $userUsedVaService->o_user_id = $orderDetailMember->o_get_user_id;
                        $userUsedVaService->o_right_id = $relMemberRight['id'];
                        $userUsedVaService->name = $relMemberRight['name'];
                        $userUsedVaService->cost = empty($relMemberRight['cost']) ? 0 : $relMemberRight['cost'];
                        $userUsedVaService->state = 2;
                        $userUsedVaService->use_time = date('Y-m-d H:i:s');
                        $userUsedVaService->finish_time = date('Y-m-d H:i:s');
                        if (!$userUsedVaService->save()) {
                            throw new Exception("保存用户已使用的增值服务信息失败");
                        }
                    }
                    $can_use_times = ($total_times - $used_times) < 1 ? 0 : ($total_times - $used_times);
                    $userRightNew = new UserRight;
                    $userRightNew->o_user_id = $orderDetailMember->o_get_user_id;
                    $userRightNew->o_right_id = $relMemberRight['id'];
                    $userRightNew->can_use_times = $can_use_times;
                    $userRightNew->used_times = $used_times;
                    $userRightNew->coming = in_array($order->order_type, [2, 4]) ? 0 : 1;
                    if (!$userRightNew->save()) {
                        throw new Exception("保存会员权益使用信息失败");
                    }
                    //如果是基因检测，还需要发码
                    $thirdCode = ThirdCode::find()->where(['o_right_id' => $userRightNew->o_right_id])->andWhere('o_user_id is null')->one();
                    if (!empty($thirdCode)) {
                        //第三方码修改
                        $thirdCode->o_user_id = $userRightNew->o_user_id;
                        $thirdCode->get_time = date('Y-m-d H:i:s');
                        $thirdCode->is_used = 0;
                        if (!$thirdCode->save()) {
                            throw new Exception;
                        }
                    }
                }
                //赠送会员
                if ($order->order_type == 4) {
                    $give_user = User::findOne($order->o_user_id);
                    $content = '手机号码为' . substr($give_user->phone, 0, 3) . '****' . substr($give_user->phone, -4) . '的用户赠送了您一份会员特权，并对您说：' . $orderDetailMember->message
                        . ' 新用户初始密码为123456，请关注公众号‘三方惠诊’，使用特权！';
                    $news = new News();
                    $news->o_user_id = $orderDetailMember->o_get_user_id;
                    $news->pic = explode('/index.php', \Yii::$app->params['frontUrl'])[0] . '/image/logo_news.png';
                    $news->title = '系统消息';
                    $news->content = $content;
                    $news->url = \Yii::$app->params['frontUrl'] . '/' . 'member/my-member';
                    $news->is_read = 0;
                    if (!$news->save()) {
                        throw new Exception("异常，发送消息异常");
                    }
                    //发送提醒短信
                    $sms = new SmsHelper();
                    $sms->Send($get_user->phone, $content);
                }
            } else {//5会员续费
                if ($my_user_member_level != $member->level) {
                    throw new Exception("异常，预购续费会员等级和会员当前等级不等");
                }

                //设置会员信息
                $userMemberExists = UserMember::find()->where(['o_user_id' => $orderDetailMember->o_get_user_id])->one();
                if (empty($userMemberExists)) {
                    throw new Exception("异常");
                }
                $userMemberExists->expiration_time = date('Y-m-d H:i:s', strtotime($userMemberExists->expiration_time) + 3600 * 24 * 365);//新购会员或升级，会员有效期设为今后的一年
                $userMemberExists->is_active = 1;
                if (!$userMemberExists->save()) {
                    throw new Exception("更新会员过期时间失败");
                }

            }
        }
    }
}